﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Web;
using System.Xml.Serialization;
using Mysoft.ModelAnalysis.Models;
using 检查页面开放.Models;

namespace 检查页面开放.Business
{
    public class CheckV3Model
    { 
        private List<V3Entity> MetadataEntityList { get; set; }

        /// <summary>
        /// 类属性
        /// </summary>
        private List<CsMember> MemberPList { get; set; }

        /// <summary>
        /// 类
        /// </summary>
        private List<CsMember> MemberTList { get; set; }

        public List<Result> ResultList { get; set; }

        public CheckV3Model()
        {
            MetadataEntityList = new List<V3Entity>();
            MemberPList = new List<CsMember>();
            MemberTList = new List<CsMember>();
            ResultList = new List<Result>();
        }

        public void Check()
        {
            //1、解析entity
            JieXiEntity();
            //4、解析后台mdoelcs类的字段
            JieXiModelFields();
            //开始比较
            Compare();
        }

        /// <summary>
        /// 解析entity
        /// </summary>
        private void JieXiEntity()
        {
            string path = Path.Combine(PathConst.RootPath, @"_metadata\Entity");

            DirectoryInfo root = new DirectoryInfo(path);
            FileStream fs = null;
            try
            {
                XmlSerializer xs = new XmlSerializer(typeof(V3Entity));
                foreach (FileInfo f in root.GetFiles())
                {
                    fs = f.OpenRead();
                    V3Entity v3Entity = (V3Entity)xs.Deserialize(fs);
                    fs.Close();
                    if (v3Entity.Name.StartsWith("s_"))
                    {
                        MetadataEntityList.Add(v3Entity);
                    }
                }
            }
            finally
            {

                if (fs != null)
                    fs.Close();
            }
        }

        /// <summary>
        /// 解析后台model的cs类的字段
        /// </summary>
        private void JieXiModelFields()
        {
            string path = Path.Combine(PathConst.RootPath, @"bin");
            DirectoryInfo root = new DirectoryInfo(path);
            XmlSerializer xs = new XmlSerializer(typeof(V3Entity));
            FileStream fs = null;
            try
            {
                foreach (FileInfo f in root.GetFiles())
                {
                    if (f.Name.StartsWith("Mysoft.Slxt") && f.Name.IndexOf("Domain", StringComparison.Ordinal) > 0&& f.Extension==".xml")
                    {
                        fs = f.OpenRead();
                        xs.Deserialize(fs);
                        doc doc = (doc)xs.Deserialize(fs);
                        fs.Close();
                        List<CsMember> member = doc.CsMembers.Member.Where(t => t.Name.StartsWith("P:")).ToList();
                        MemberPList.AddRange(member);
                        List<CsMember> memberT = doc.CsMembers.Member.Where(t => t.Name.StartsWith("T:")).ToList();
                        MemberTList.AddRange(memberT);
                    }
                }
            }
            finally
            {
                if (fs != null)
                    fs.Close();
            }
        }

        private void Compare()
        {
            foreach (V3Entity v3Entity in MetadataEntityList)
            {
                //查找类s_PriceChgLog  PriceChgLogEntity
                CsMember tClas = MemberTList.FirstOrDefault(t => t.Name.EndsWith($".{v3Entity.Name.Split('_').Last()}Entity"));
                if (tClas == null)
                {
                    ResultList.Add(new Result
                    {
                        Content = $"表：{v3Entity.Name}不存在对应的类"
                    });
                    continue;
                }
                //查找类的字段
                IEnumerable<CsMember> classFields = MemberPList.Where(t => t.Name.StartsWith(tClas.Name));
                //cs类有，元数据没有
                foreach (var classField in classFields)
                {
                    if (v3Entity.Attributes.MetadataAttributes.Any(t => t.Name == classField.Name) == false)
                    {
                        ResultList.Add(new Result
                        {
                            Content = $"{tClas.Name}类中多余字段{classField.Name}"
                        });
                    }
                }
                // 元数据有，类中没有
                foreach (V3MetadataAttribute v3MetadataAttribute in v3Entity.Attributes.MetadataAttributes)
                {
                    if (classFields.Any(t => t.Name == v3MetadataAttribute.Name) == false)
                    {
                        ResultList.Add(new Result
                        {
                            Content = $"{tClas.Name}中缺少字段{v3MetadataAttribute.Name}"
                        });
                    }
                }

            }
        }
    }
}



#region 元数据
[XmlRoot("MetadataEntity")]
public class V3Entity
{
    /// <summary>
    /// businessUnitCode
    /// </summary>
    [XmlAttribute(AttributeName = "businessUnitCode")]
    public string BusinessUnitCode { get; set; }
    /// <summary>
    /// Name 例如：s_Room
    /// </summary>
    [XmlAttribute(AttributeName = "Name")]
    public string Name { get; set; }

    /// <summary>
    /// 属性列表
    /// </summary>
    [XmlElement("Attributes")]
    public V3Attributes Attributes { get; set; }
}


public class V3Attributes
{
    /// <summary>
    /// 属性列表
    /// </summary>
    [XmlElement("MetadataAttribute")]
    public List<V3MetadataAttribute> MetadataAttributes { get; set; }
}

public class V3MetadataAttribute
{

    /// <summary>
    /// 字段名称
    /// </summary>
    public string Name { get; set; }
    /// <summary>
    /// 描述
    /// </summary>
    public string DisplayName { get; set; }
    /// <summary>
    /// 字段类型
    /// </summary>
    public string DbType { get; set; }
}
#endregion

#region csmodel

[XmlRoot("doc")]
public class doc
{
    /// <summary>
    /// members
    /// </summary>
    [XmlElement("members")]
    public CsMembers CsMembers { get; set; }
}


public class CsMembers
{
    [XmlElement("member")]
    public List<CsMember> Member { get; set; }
}

public class CsMember
{
    [XmlAttribute("name")]
    public string Name { get; set; }
}

#endregion

public class Result
{
    public string Content { get; set; }
}